package com.anyext.storage.impl;

import java.util.List;
import java.util.Map;

import com.anyext.storage.JdbcTemplate;
import com.anyext.storage.Page;
import com.anyext.storage.RouterHolder;
import com.anyext.storage.SessionException;
import com.anyext.storage.SqlMapTemplate;
import com.anyext.storage.StorageContext;
import com.anyext.storage.dialect.Dialect;
import com.anyext.storage.exception.ParseException;
import com.anyext.storage.jdbc.RowCallback;
import com.anyext.storage.mapping.CustomSql;
import com.anyext.storage.mapping.RuntimeSql;
import com.anyext.storage.mapping.SqlMap;
import com.anyext.storage.util.SqlParser;

public class SqlMapTemplateImpl implements SqlMapTemplate {

	private JdbcTemplate	jdbcTemplate;

	protected SqlMapTemplateImpl(JdbcTemplate jdbcTemplate) throws SessionException {
		this.jdbcTemplate = jdbcTemplate;
	}

	@Override
	public <V> Map<String, V> select(String statement) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <V> Map<String, V> select(String statement, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> T selectOne(String statement) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> T selectOne(String statement, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <E> List<E> selectList(String statement) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <E> List<E> selectList(String statement, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <E> List<E> selectList(String statement, Page page) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <E> List<E> selectList(String statement, Page page, Object... parameters) throws SessionException {
		CustomSql customSql = StorageContext.getCustomSql(statement);
		if (customSql == null) {
			SqlMap sqlMap = StorageContext.getSqlMap(statement);
			if (sqlMap == null) {
				throw new SessionException("can not find mapping sql[" + statement + "]");
			}
			try {
				customSql = SqlParser.parseCustomSql(sqlMap);
			} catch (ParseException e) {
				throw new SessionException("parse mapping sql[" + statement + "] error", e);
			}
			StorageContext.addCustomSql(customSql);
		}
		
		RouterHolder.useGroup(customSql.getGroup());
		
		RuntimeSql runtimeSql = SqlParser.parseRuntimeSql(customSql, parameters);
		RowCallback<E> rowCallback = customSql.getRowCallback();
		String sql = runtimeSql.getRuntimeSql();
		
		if(page != null) {
			sql = SqlParser.parseCountSql(runtimeSql.getRuntimeSql());
			Number count = jdbcTemplate.queryForObject(sql, runtimeSql.getRuntimeParams(), Integer.class);
			if (count != null && count.intValue() > 0) {
				page.setDataCount(count.intValue());
				
				Dialect dialect = customSql.getDialect();
				sql = dialect.getLimitSql(runtimeSql.getRuntimeSql(), page.getFirstResult(), page.getMaxResult());
			} else {
				page.setDataCount(0);
				return null;
			}
		}
		jdbcTemplate.query(sql, rowCallback, runtimeSql.getRuntimeParams());
		return rowCallback.getResults();
	}

	@Override
	public <K, V> Map<K, V> selectMap(String statement, String mapKey) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <K, V> Map<K, V> selectMap(String statement, String mapKey, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <K, V> Map<K, V> selectMap(String statement, String mapKey, Page page) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <K, V> Map<K, V> selectMap(String statement, String mapKey, Page page, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int insert(String statement) throws SessionException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int insert(String statement, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int update(String statement) throws SessionException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int update(String statement, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int delete(String statement) throws SessionException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int delete(String statement, Object... parameters) throws SessionException {
		// TODO Auto-generated method stub
		return 0;
	}
}
